package network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpEchoServer {
    //创建一个DatagramSocket对象 这个就相当于一个网卡文件
    private DatagramSocket socket = null;

    public UdpEchoServer(int port) throws SocketException {
        //这样写就是手动指定端口
        socket = new DatagramSocket(port);

        //socket = new DatagramSocket();  这样写就是系统自动分配端口
    }

    public void start() throws IOException {
        System.out.println("服务器启动!");
        while (true) {
            //1. 读取请求并解析
            //这里首先要创建出数据报类型的对象
            //此处的requestPacket对象就是作为输出型参数进行传递
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(requestPacket);
            //在receive之后,requestPacket中已经存储好了二进制数据

            //但是要想显示出来,就需要把这个二进制转为字符串
            //此处意思就是从 0 到数据的最大长度
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());

            //2.根据请求计算相应
            //由于是回显服务器,请求是啥样,相应就是啥样
            String response = process(request);

            //3.把响应写回到客户端中
            //此时搞一个响应对象,DatagramPacket,在这个里面构造刚才的数据,再返回
            //注意response.getBytes().length 和 response.length 是不一样的，
            // 一个是获取字节的长度，另一个是获取字符的长度。如果response全是英文字符串，那就没事。但是如有中文的话就可能会出现问题
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);
            //打印日志文件
            System.out.printf("[%s:%d] req=%s, resp=%s\n",requestPacket.getAddress().toString(),
                    requestPacket.getPort(),request,response);
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer server = new UdpEchoServer(9090);
        server.start();
    }
}